Clean up the TPM stack a bit.
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 7 Feb 2006 20:38:44 +0000 (20:38 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 7 Feb 2006 20:38:44 +0000 (20:38 +0000)
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
linux-2.6-xen-sparse/drivers/char/tpm/tpm.c
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.h
linux-2.6-xen-sparse/include/xen/tpmfe.h

index 14f9539a4b5445a275d9327af7569318721011c1..aefbab67e3d0dcdc1dc454cb5b2a7c9a16ad9aa7 100644 (file)
@@ -67,9 +67,6 @@ static ssize_t tpm_transmit(struct tpm_chip * chip, const char *buf,
        u32 count;
        unsigned long stop;
 
-       if (!chip)
-               return -ENODEV;
-
        count = be32_to_cpu(*((__be32 *) (buf + 2)));
 
        if (count == 0)
index 9767350828b516b04ebecb7f0b53ad33fc5686dc..a3097fa829292fc490ebd93ee7edabcd233fe127 100644 (file)
@@ -42,7 +42,6 @@ struct transmission {
        unsigned int request_len;
        unsigned char *rcv_buffer;
        unsigned int  buffersize;
-       struct tpm_chip     *chip;
        unsigned int flags;
 };
 
@@ -75,6 +74,8 @@ static struct data_exchange dataex;
 
 static unsigned long disconnect_time;
 
+static struct tpmfe_device tpmfe;
+
 /* local function prototypes */
 static void __exit cleanup_xen(void);
 
@@ -119,7 +120,7 @@ transmission_free(struct transmission *t)
 static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
 {
        int ret_size = 0;
-       struct transmission *t, *temp;
+       struct transmission *t;
 
        /*
         * The list with requests must contain one request
@@ -127,8 +128,9 @@ static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
         * was passed to me from the front-end.
         */
        if (dataex.current_request != ptr) {
-               printk("WARNING: The request pointer is different than the pointer "
-                      "the shared memory driver returned to me. %p != %p\n",
+               printk("WARNING: The request pointer is different than the "
+                      "pointer the shared memory driver returned to me. "
+                      "%p != %p\n",
                       dataex.current_request, ptr);
        }
 
@@ -144,16 +146,16 @@ static int tpm_recv(const u8 *buffer, size_t count, const void *ptr)
                return 0;
        }
 
-       if (NULL != (temp = dataex.current_request)) {
-               transmission_free(temp);
+       if (NULL != (t = dataex.current_request)) {
+               transmission_free(t);
                dataex.current_request = NULL;
        }
 
        t = transmission_alloc();
-       if (NULL != t) {
+       if (t) {
                unsigned long flags;
                t->rcv_buffer = kmalloc(count, GFP_KERNEL);
-               if (NULL == t->rcv_buffer) {
+               if (! t->rcv_buffer) {
                        transmission_free(t);
                        return -ENOMEM;
                }
@@ -258,10 +260,6 @@ static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
 
        if (t != NULL) {
                unsigned int error = 0;
-               t->rcv_buffer = NULL;
-               t->buffersize = 0;
-               t->chip = chip;
-
                /*
                 * Queue the packet if the driver below is not
                 * ready, yet, or there is any packet already
@@ -304,9 +302,11 @@ static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
                                struct transmission *qt = (struct transmission *) dataex.queued_requests.next;
                                list_del(&qt->next);
                                dataex.current_request = qt;
-                               spin_unlock_irqrestore(&dataex.req_list_lock, flags);
+                               spin_unlock_irqrestore(&dataex.req_list_lock,
+                                                      flags);
 
-                               rc = tpm_fe_send(qt->request,
+                               rc = tpm_fe_send(tpmfe.tpm_private,
+                                                qt->request,
                                                 qt->request_len,
                                                 qt);
 
@@ -351,7 +351,8 @@ static int tpm_xen_send(struct tpm_chip *chip, u8 * buf, size_t count)
                                 * amount of bytes in the request and
                                 * a void * pointer (here: transmission structure)
                                 */
-                               rc = tpm_fe_send(buf, count, t);
+                               rc = tpm_fe_send(tpmfe.tpm_private,
+                                                buf, count, t);
                                /*
                                 * The generic TPM driver will call
                                 * the function to receive the response.
@@ -373,7 +374,8 @@ queue_it:
                                 * queue it.
                                 */
                                dataex.flags |= DATAEX_FLAG_QUEUED_ONLY;
-                               list_add_tail(&t->next, &dataex.queued_requests);
+                               list_add_tail(&t->next,
+                                             &dataex.queued_requests);
                                rc = 0;
                        }
                }
@@ -512,7 +514,7 @@ static void __exit cleanup_xen(void)
        tpm_fe_unregister_receiver();
 }
 
-fs_initcall(init_xen);
+module_init(init_xen);
 module_exit(cleanup_xen);
 
 MODULE_AUTHOR("Stefan Berger (stefanb@us.ibm.com)");
index f6d426477213f658bf74527965324d317143cb75..8d76033eb942eb83a51a23c25b0bc5e8dd9e50d0 100644 (file)
 
 /* locally visible variables */
 static grant_ref_t gref_head;
-static struct tpm_private my_private;
+static struct tpm_private *my_priv;
 
 /* local function prototypes */
 static irqreturn_t tpmif_int(int irq,
                              void *tpm_priv,
                              struct pt_regs *ptregs);
 static void tpmif_rx_action(unsigned long unused);
-static void tpmif_connect(u16 evtchn, domid_t domid);
+static void tpmif_connect(struct tpm_private *tp, domid_t domid);
 static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
 static int tpm_allocate_buffers(struct tpm_private *tp);
 static void tpmif_set_connected_state(struct tpm_private *tp,
@@ -101,7 +101,7 @@ tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
 
 static inline struct tx_buffer *tx_buffer_alloc(void)
 {
-       struct tx_buffer *txb = kmalloc(sizeof (struct tx_buffer),
+       struct tx_buffer *txb = kzalloc(sizeof (struct tx_buffer),
                                        GFP_KERNEL);
 
        if (txb) {
@@ -117,6 +117,31 @@ static inline struct tx_buffer *tx_buffer_alloc(void)
 }
 
 
+/**************************************************************
+ Utility function for the tpm_private structure
+**************************************************************/
+static inline void tpm_private_init(struct tpm_private *tp)
+{
+       spin_lock_init(&tp->tx_lock);
+       init_waitqueue_head(&tp->wait_q);
+}
+
+static struct tpm_private *tpm_private_get(void)
+{
+       if (!my_priv) {
+               my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
+               if (my_priv) {
+                       tpm_private_init(my_priv);
+               }
+        }
+        return my_priv;
+}
+
+static inline void tpm_private_free(struct tpm_private *tp)
+{
+       kfree(tp);
+}
+
 /**************************************************************
 
  The interface to let the tpm plugin register its callback
@@ -131,10 +156,9 @@ static struct tpmfe_device *upperlayer_tpmfe;
 /*
  * Send data via this module by calling this function
  */
-int tpm_fe_send(const u8 * buf, size_t count, void *ptr)
+int tpm_fe_send(struct tpm_private *tp, const u8 * buf, size_t count, void *ptr)
 {
        int sent = 0;
-       struct tpm_private *tp = &my_private;
 
        down(&suspend_lock);
        sent = tpm_xmit(tp, buf, count, 0, ptr);
@@ -155,6 +179,7 @@ int tpm_fe_register_receiver(struct tpmfe_device *tpmfe_dev)
        if (NULL == upperlayer_tpmfe) {
                upperlayer_tpmfe = tpmfe_dev;
                tpmfe_dev->max_tx_size = TPMIF_TX_RING_SIZE * PAGE_SIZE;
+               tpmfe_dev->tpm_private = tpm_private_get();
        } else {
                rc = -EBUSY;
        }
@@ -197,10 +222,9 @@ static int tpm_fe_send_upperlayer(const u8 * buf, size_t count,
 **************************************************************/
 
 static int setup_tpmring(struct xenbus_device *dev,
-                         struct tpmfront_info * info)
+                         struct tpm_private *tp)
 {
        tpmif_tx_interface_t *sring;
-       struct tpm_private *tp = &my_private;
        int err;
 
        sring = (void *)__get_free_page(GFP_KERNEL);
@@ -219,13 +243,13 @@ static int setup_tpmring(struct xenbus_device *dev,
                xenbus_dev_fatal(dev, err, "allocating grant reference");
                goto fail;
        }
-       info->ring_ref = err;
+       tp->ring_ref = err;
 
        err = xenbus_alloc_evtchn(dev, &tp->evtchn);
        if (err)
                goto fail;
 
-       tpmif_connect(tp->evtchn, dev->otherend_id);
+       tpmif_connect(tp, dev->otherend_id);
 
        return 0;
 fail:
@@ -233,11 +257,11 @@ fail:
 }
 
 
-static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
+static void destroy_tpmring(struct tpm_private *tp)
 {
        tpmif_set_connected_state(tp, 0);
        if (tp->tx != NULL) {
-               gnttab_end_foreign_access(info->ring_ref, 0,
+               gnttab_end_foreign_access(tp->ring_ref, 0,
                                          (unsigned long)tp->tx);
                tp->tx = NULL;
        }
@@ -249,13 +273,13 @@ static void destroy_tpmring(struct tpmfront_info *info, struct tpm_private *tp)
 
 
 static int talk_to_backend(struct xenbus_device *dev,
-                           struct tpmfront_info *info)
+                           struct tpm_private *tp)
 {
        const char *message = NULL;
        int err;
        xenbus_transaction_t xbt;
 
-       err = setup_tpmring(dev, info);
+       err = setup_tpmring(dev, tp);
        if (err) {
                xenbus_dev_fatal(dev, err, "setting up ring");
                goto out;
@@ -269,14 +293,14 @@ again:
        }
 
        err = xenbus_printf(xbt, dev->nodename,
-                           "ring-ref","%u", info->ring_ref);
+                           "ring-ref","%u", tp->ring_ref);
        if (err) {
                message = "writing ring-ref";
                goto abort_transaction;
        }
 
        err = xenbus_printf(xbt, dev->nodename,
-                           "event-channel", "%u", my_private.evtchn);
+                           "event-channel", "%u", tp->evtchn);
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
@@ -301,7 +325,7 @@ abort_transaction:
        if (message)
                xenbus_dev_error(dev, err, "%s", message);
 destroy_tpmring:
-       destroy_tpmring(info, &my_private);
+       destroy_tpmring(tp);
 out:
        return err;
 }
@@ -312,7 +336,7 @@ out:
 static void backend_changed(struct xenbus_device *dev,
                            XenbusState backend_state)
 {
-       struct tpm_private *tp = &my_private;
+       struct tpm_private *tp = dev->data;
        DPRINTK("\n");
 
        switch (backend_state) {
@@ -343,8 +367,8 @@ static int tpmfront_probe(struct xenbus_device *dev,
                           const struct xenbus_device_id *id)
 {
        int err;
-       struct tpmfront_info *info;
        int handle;
+       struct tpm_private *tp = tpm_private_get();
 
        err = xenbus_scanf(XBT_NULL, dev->nodename,
                           "handle", "%i", &handle);
@@ -356,20 +380,12 @@ static int tpmfront_probe(struct xenbus_device *dev,
                return err;
        }
 
-       info = kmalloc(sizeof(*info), GFP_KERNEL);
-       if (!info) {
-               err = -ENOMEM;
-               xenbus_dev_fatal(dev,err,"allocating info structure");
-               return err;
-       }
-       memset(info, 0x0, sizeof(*info));
-
-       info->dev = dev;
-       dev->data = info;
+        tp->dev = dev;
+        dev->data = tp;
 
-       err = talk_to_backend(dev, info);
+       err = talk_to_backend(dev, tp);
        if (err) {
-               kfree(info);
+                tpm_private_free(tp);
                dev->data = NULL;
                return err;
        }
@@ -379,18 +395,15 @@ static int tpmfront_probe(struct xenbus_device *dev,
 
 static int tpmfront_remove(struct xenbus_device *dev)
 {
-       struct tpmfront_info *info = dev->data;
-
-       destroy_tpmring(info, &my_private);
-
-       kfree(info);
+        struct tpm_private *tp = dev->data;
+       destroy_tpmring(tp);
        return 0;
 }
 
 static int
 tpmfront_suspend(struct xenbus_device *dev)
 {
-       struct tpm_private *tp = &my_private;
+       struct tpm_private *tp = dev->data;
        u32 ctr;
 
        /* lock, so no app can send */
@@ -420,17 +433,15 @@ tpmfront_suspend(struct xenbus_device *dev)
 static int
 tpmfront_resume(struct xenbus_device *dev)
 {
-       struct tpmfront_info *info = dev->data;
-       return talk_to_backend(dev, info);
+        struct tpm_private *tp = dev->data;
+       return talk_to_backend(dev, tp);
 }
 
 static void
-tpmif_connect(u16 evtchn, domid_t domid)
+tpmif_connect(struct tpm_private *tp, domid_t domid)
 {
        int err;
-       struct tpm_private *tp = &my_private;
 
-       tp->evtchn = evtchn;
        tp->backend_id = domid;
 
        err = bind_evtchn_to_irqhandler(tp->evtchn,
@@ -477,9 +488,9 @@ tpm_allocate_buffers(struct tpm_private *tp)
 }
 
 static void
-tpmif_rx_action(unsigned long unused)
+tpmif_rx_action(unsigned long priv)
 {
-       struct tpm_private *tp = &my_private;
+       struct tpm_private *tp = (struct tpm_private *)priv;
 
        int i = 0;
        unsigned int received;
@@ -529,6 +540,7 @@ tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
        unsigned long flags;
 
        spin_lock_irqsave(&tp->tx_lock, flags);
+       tpmif_rx_tasklet.data = (unsigned long)tp;
        tasklet_schedule(&tpmif_rx_tasklet);
        spin_unlock_irqrestore(&tp->tx_lock, flags);
 
@@ -678,12 +690,6 @@ tpmif_init(void)
                                             &gref_head ) < 0) {
                return -EFAULT;
        }
-       /*
-        * Only don't send the driver status when we are in the
-        * INIT domain.
-        */
-       spin_lock_init(&my_private.tx_lock);
-       init_waitqueue_head(&my_private.wait_q);
 
        init_tpm_xenbus();
 
index fdc0b151c835fdc3e4f0ead566182d2a4ea4ac51..66568ba64b94aa360d1ff0302da5d5a79db2bf30 100644 (file)
@@ -17,9 +17,6 @@ struct tpm_private {
        domid_t backend_id;
        wait_queue_head_t wait_q;
 
-};
-
-struct tpmfront_info {
        struct xenbus_device *dev;
        int ring_ref;
 };
index 78f31a7e041e4d0d3a0f79a4ee79ea31fa01a804..9b8ea7c2a59c7730e15052221e7ca63dac5dc19c 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef TPM_FE_H
 #define TPM_FE_H
 
+struct tpm_private;
+
 struct tpmfe_device {
        /*
         * Let upper layer receive data from front-end
@@ -19,6 +21,11 @@ struct tpmfe_device {
         * for allocation of buffers.
         */
        unsigned int max_tx_size;
+       /*
+        * The following is a private structure of the underlying
+        * driver. It's expected as first parameter in the send function.
+        */
+       struct tpm_private *tpm_private;
 };
 
 enum {
@@ -26,7 +33,7 @@ enum {
        TPMFE_STATUS_CONNECTED = 0x1
 };
 
-int tpm_fe_send(const u8 * buf, size_t count, void *ptr);
+int tpm_fe_send(struct tpm_private * tp, const u8 * buf, size_t count, void *ptr);
 int tpm_fe_register_receiver(struct tpmfe_device *);
 void tpm_fe_unregister_receiver(void);